Contents  >  Welcome  >  Getting Started

Welcome to the Delphi for Microsoftâ .NET Preview

Software developers have asked many questions about Microsoft's .NET Framework since it was first introduced. Some of the confusion stems from the fact that the .NET Framework isn't just one thing. The .NET Framework is an initiative begun by Microsoft, to facilitate the development of web-based applications, through the use of standardized protocols such as HTTP, and SOAP. The .NET Framework class library and common language runtime are software development environments, created to support these new applications and web services. The .NET initiative consists of several standards and technologies, which together will fundamentally change the way software is developed on the Windows platform:

 

 

As a new software development environment, the .NET Framework has already produced many positive effects. For starters, the .NET Framework implements rules for deploying assemblies. The rules define a specific location where developers should deploy assemblies that will be shared by multiple applications. It allows different versions of the same assembly to be deployed side-by-side, so that applications are not broken when a different application installs a newer version of the same shared component.

 

The CIL produced by the compiler can be analyzed for type safety before being executed, preventing potentially dangerous type coercions that can be exploited by malicious code.

 

Another benefit comes from the automatic memory management provided by the CLR. The .NET Framework's garbage collected memory manager tracks all memory allocations, and recovers memory when it determines that memory is no longer referenced.

 

A full discussion of the .NET Framework is found on Microsoft's MSDN website. The Borland Developer Network also features technical articles, and registered customers will be able to access updates on Borland's .NET tools as they become available.

Delphi and the .NET Framework

The .NET Framework is a radical departure from the old ways of developing software for Windows, but some of the ideas it brings to the table aren't new. In fact the idea for compiling to a neutral intermediate language goes back all the way to the late 1950's. In 1958, an article by Melvin E. Conway appeared in the Journal for the Association for Computing Machinery, titled "Proposal For An UNCOL" (Universal Computer-Oriented Language). Conway's paper describes an intermediate language, which he called SML (simple machine language). The article even mentions tagging the intermediate code with metadata, which would serve as hints for the final translation to native machine instructions.

 

One of the motivations behind the UNCOL was to free programmers from having to worry about the hardware-specific intricacies of each platform. To bring the lofty goal of portability to fruition required much more than just the definition of an intermediate language. Not only must compilers produce intermediate code, but also an environment must be created in which to execute that code. The virtual execution system (VES) provides the services required to make platform neutrality a viable goal.

 

The road towards a universal language and execution environment has been long. Today, virtual execution environments such as the Java Virtual Machine (JVM) and Microsoft's Common Language Runtime give programmers some of the long sought after portability. Complex graphical user interfaces have proven to be a troublesome aspect of developing a truly portable application, but even so, intermediate languages, runtime compilation, and virtual execution systems have greatly broadened developers' deployment opportunities.

 

It is Borland's intention to evolve the Delphi language and its runtime libraries to fully support the new execution model of Microsoft's CLR. Further, it is Borland's intention to so in a way that makes migration to the new execution model as seamless as possible for Delphi developers. The Delphi language will be more than a CLR consumer. It will be a CLR extender, giving developers a tremendous advantage by allowing them to leverage their existing code, fully exploit the CLR, and extend the .NET Framework Class Library.

Portability in the CLR

Runtime compilation is the key to portability in a virtual execution system. It is the mechanism that allows developers to target such disparate hardware platforms as Intel's Pentium 4 and ARM processors, with a single code base. The Delphi for .NET Preview compiler already produces CLS-compliant intermediate code, although the compiler is not yet feature-complete at this stage.

 

The CLR is not an interpreted execution environment. The runtime, or "Just in Time" (JIT) compiler always produces native machine instructions prior to execution. The .NET Framework SDK includes a utility called ngen, which can be used to compile CIL to native instructions and then cache the compiled code to disk. There are still advantages to using runtime compilation however. The JIT compiler has far greater knowledge of the end-user's execution environment; therefore it can take advantage of processor specific optimizations that utilities like ngen aren't aware of.

 

The JIT compiler performs many of the same optimizations done by the current Delphi compiler, including

 

 

The JIT also performs automatic function inlining, which can greatly improve performance of nested function calls.

 

While JIT compilation broadens horizons, no claims such as "Write once, run anywhere" have been made with regard to the .NET Framework. Non-graphical code is fully portable between platforms that provide a CLI-compliant runtime environment. It is not reasonable, however, to expect a user interface to be 100% portable from a desktop running at a resolution of 1600x1200 pixels, to a handheld device capable of displaying only 240x320 pixels. Certainly, developers should plan on making significant design considerations when targeting both the desktop, and handheld devices.

Managed Execution in the CLR

Language compilers that target the CLR are said to produce managed applications. The term managed is used because the CLR completely takes over the process of loading, verifying, compiling, optimizing, and executing the CIL produced by the compiler. The CLR features a generational, garbage collected memory manager, which tracks memory usage and frees memory when it is no longer referenced. The .NET Framework Class Library exposes many more services provided by the CLR, such as type reflection, a unified exception model, and rich debugging support. Code that is compiled to native machine instructions (in the traditional sense) is called unmanaged code, since it is not loaded or executed by the CLR.

 

It is expected that much of your existing Delphi code will compile and run in the CLR, but keep in mind that not all of the programming practices allowed in the native Win32 environment are sanctioned by the CLR. There is a distinction between managed and unmanaged code, and, within the CLR, there is a distinction between safe and unsafe code.

 

Prior to compilation, the JIT compiler performs static analysis of CIL code. This verification process ensures the code is type-safe:

 

 

Microsoft also includes a command line utility with the .NET Framework SDK, called peverify. This utility is used to confirm that a managed code module contains safe IL code.

 

It is important to realize that the JIT compiler does not compile an application in its entirety when it is first loaded. JIT compilation truly means "just in time", and it might not happen until a method is actually called. This can lead to situations where code will compile and pass the analysis of peverify (and the JIT compiler), but that code will not run when deployed, because the JIT compiler cannot find the method.

 

As long as you are compiling and deploying to the same version of the runtime, all is well. However, as new versions of the .NET Framework appear, you might begin to see this problem. For example, it can happen if you build against a newer version of the .NET Framework, and your code is run against a prior version.

 

Type-safe verification is possible because .NET Framework assemblies are self-describing. The metadata emitted by the compiler fully describes the types implemented and referenced by the assembly. CIL code that can be verified said to be safe code. Code that cannot be verified is unsafe. Not all managed code is safe code, and the .NET Framework allows system administrators to set their local policies to determine whether or not the CLR is allowed to execute unsafe code.

 

In order to produce safe code, certain features of the Delphi language had to either be removed, or severely restricted. In particular, operations on absolute memory addresses are being deprecated. Unsafe types such as PChar and variant records are currently the subjects of ongoing research to determine how they will be supported in future revisions of the Delphi compiler.

 

The CLR provides automatic memory management, so the memory allocation functions GetMem(), FreeMem(), and ReallocMem() are deprecated. The constructor-destructor mechanisms of Delphi are being rewritten to use the dispose pattern, so that your existing classes can gain the advantage of automatic memory management, and you can write new classes with the same Create/Destroy constructors and destructors that you are already familiar with.

 

The .NET Framework's bridge to unmanaged code, called P/Invoke (for Platform Invoke), is supported in Delphi for .NET. You can call unmanaged code (e.g. the Win32 API), using the DllImport custom attribute. The ability to use unmanaged COM servers is a feature of the .NET Framework, and is also supported in Delphi for .NET.

Language Interoperability and Integration

Beyond platform neutrality, the CLR offers another powerful capability: true integration of different programming languages. The CLR is designed from the ground up to allow both language interoperability (in the COM sense), and transparent usage of types developed in different programming languages. The CLR does not know what language was used to develop a .NET component or application. As long as the compiler complies with the CLS, all of the interoperability and integration features of the CLR are automatically available.

 

Delphi is going to be a first-class citizen in the .NET Framework. You can use Delphi to write managed applications using the .NET Framework Class Library directly. You can also extend those classes with Delphi for .NET using the traditional mechanism of inheritance. Furthermore, since Delphi for .NET will be fully CLS compliant, developers writing in other languages can use and extend components written in Delphi. And if that's not enough, remember that this bridge is a two-way street - Delphi developers can extend components written in other .NET languages such as Visual Basic and C#.

Assemblies and Delphi Packages

The basic unit of deployment in the .NET Framework is called an assembly. An assembly can consist of IL code, data such as images and resource strings, or both. An assembly can be a single file (e.g. a dynamic link library, or executable), or it can be made up of several files. Each assembly contains a piece of metadata called the manifest. The manifest describes all the files that make up the assembly, as well as all the files the assembly depends on.

 

Because they contain both code and data, .NET assemblies are analogous to Delphi packages. Indeed, in Delphi for .NET, package syntax will produce an assembly.

 


Top  |  Contents  |  Copyrights  |  Borland Developer Network  |  Borland Home